{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# G.A.N\n",
    "> Generative Adversial Network:\n",
    "> -  The main focus for GAN is to generate data from scratch.\n",
    "> -  It brings us closer to understanding intelligence.\n",
    "- It trains two deep networks, called Generator and Discriminator, that compete and cooperate with each other. In the course of training, both networks eventually learn how to perform their tasks.\n",
    "> > - The generator never actually sees examples from the domain and is adapted based on how well the discriminator performs."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[Original Article: How to Develop a 1D GAN](https://machinelearningmastery.com/how-to-develop-a-generative-adversarial-network-for-a-1-dimensional-function-from-scratch-in-keras/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "# The Import Statements:\n",
    "from matplotlib import pyplot\n",
    "import numpy as np\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense\n",
    "from keras.utils.vis_utils import plot_model"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Defining a 1 D function:\n",
    "> y=f(x)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "def function_1D(x):\n",
    "    return x*x"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "inputs=np.arange(-0.5,0.6,0.1)\n",
    "outputs=[function_1D(x) for x in inputs]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# plot the result\n",
    "pyplot.plot(inputs, outputs)\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Defining random values\n",
    "def generate_samples(n=100):\n",
    "    x1=np.random.rand(n)-0.5\n",
    "    x2=x1*x1\n",
    "    x1=x1.reshape(n,1)\n",
    "    x2=x2.reshape(n,1)\n",
    "    return np.hstack((x1,x2))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# generate samples and plotting them\n",
    "data = generate_samples()\n",
    "\n",
    "pyplot.scatter(data[:, 0], data[:, 1])\n",
    "pyplot.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Note:\n",
    "> *a sample is comprised of a vector with two elements, one for the input and one for the output of our one-dimensional function.*"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The Discriminator\n",
    "- The difference from a typical CNN is the absence of max-pooling in between layers.\n",
    "- will have 1 hidden layer with 25 nodes.\n",
    "- will use the ReLU activation function\n",
    "- The output layer will have 1 node for the binary classification using the sigmoid activation function.\n",
    "- Loss Function: Binary Cross Entropy\n",
    "- Optimizer : Adam version of stochastic Gradient Descent"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Code for the Discriminator Unit:\n",
    "def define_discriminator(n_inputs=2):\n",
    "\tmodel = Sequential()\n",
    "\tmodel.add(Dense(25, activation='relu', kernel_initializer='he_uniform', input_dim=n_inputs))\n",
    "\tmodel.add(Dense(1, activation='sigmoid'))\n",
    "\t# compile model\n",
    "\tmodel.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])\n",
    "\treturn model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_1\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense_1 (Dense)              (None, 25)                75        \n",
      "_________________________________________________________________\n",
      "dense_2 (Dense)              (None, 1)                 26        \n",
      "=================================================================\n",
      "Total params: 101\n",
      "Trainable params: 101\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# define the discriminator model\n",
    "model = define_discriminator()\n",
    "# summarize the model\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_real_samples(n):\n",
    "    x1=np.random.rand(n)-0.5\n",
    "    x2=x1*x1\n",
    "    x1=x1.reshape(n,1)\n",
    "    x2=x2.reshape(n,1)\n",
    "    X= np.hstack((x1,x2))\n",
    "    y=np.ones((n,1))\n",
    "    return X,y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "def generate_fake_samples(n):\n",
    "\t# generate inputs in [-1, 1]\n",
    "\tX1 = -1 + np.random.rand(n) * 2\n",
    "\t# generate outputs in [-1, 1]\n",
    "\tX2 = -1 + np.random.rand(n) * 2\n",
    "\t# stack arrays\n",
    "\tX1 = X1.reshape(n, 1)\n",
    "\tX2 = X2.reshape(n, 1)\n",
    "\tX = np.hstack((X1, X2))\n",
    "\t# generate class labels\n",
    "\ty = np.zeros((n, 1))\n",
    "\treturn X, y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "#training the discriminator model\n",
    "def train_discriminator(model, n_epochs=1000, n_batch=128):\n",
    "\thalf_batch = int(n_batch / 2)\n",
    "\t# run epochs manually\n",
    "\tfor i in range(n_epochs):\n",
    "\t\t# generate real examples\n",
    "\t\tX_real, y_real = generate_real_samples(half_batch)\n",
    "\t\t# update model\n",
    "\t\tmodel.train_on_batch(X_real, y_real)\n",
    "\t\t# generate fake examples\n",
    "\t\tX_fake, y_fake = generate_fake_samples(half_batch)\n",
    "\t\t# update model\n",
    "\t\tmodel.train_on_batch(X_fake, y_fake)\n",
    "\t\t# evaluate the model\n",
    "\t\t_, acc_real = model.evaluate(X_real, y_real, verbose=0)\n",
    "\t\t_, acc_fake = model.evaluate(X_fake, y_fake, verbose=0)\n",
    "\t\tprint(i, acc_real, acc_fake)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 0.5 0.15625\n",
      "1 0.546875 0.25\n",
      "2 0.578125 0.21875\n",
      "3 0.5625 0.21875\n",
      "4 0.640625 0.234375\n",
      "5 0.515625 0.40625\n",
      "6 0.515625 0.46875\n",
      "7 0.59375 0.390625\n",
      "8 0.5625 0.46875\n",
      "9 0.53125 0.4375\n",
      "10 0.46875 0.484375\n",
      "11 0.421875 0.53125\n",
      "12 0.46875 0.484375\n",
      "13 0.515625 0.5625\n",
      "14 0.46875 0.6875\n",
      "15 0.5625 0.515625\n",
      "16 0.515625 0.53125\n",
      "17 0.53125 0.5\n",
      "18 0.484375 0.609375\n",
      "19 0.40625 0.5\n",
      "20 0.46875 0.671875\n",
      "21 0.484375 0.59375\n",
      "22 0.546875 0.609375\n",
      "23 0.375 0.53125\n",
      "24 0.421875 0.53125\n",
      "25 0.34375 0.65625\n",
      "26 0.421875 0.484375\n",
      "27 0.421875 0.578125\n",
      "28 0.328125 0.546875\n",
      "29 0.359375 0.640625\n",
      "30 0.4375 0.609375\n",
      "31 0.296875 0.484375\n",
      "32 0.296875 0.53125\n",
      "33 0.515625 0.625\n",
      "34 0.359375 0.59375\n",
      "35 0.40625 0.65625\n",
      "36 0.359375 0.6875\n",
      "37 0.28125 0.578125\n",
      "38 0.328125 0.578125\n",
      "39 0.328125 0.671875\n",
      "40 0.40625 0.671875\n",
      "41 0.296875 0.515625\n",
      "42 0.296875 0.578125\n",
      "43 0.296875 0.625\n",
      "44 0.34375 0.625\n",
      "45 0.390625 0.671875\n",
      "46 0.375 0.609375\n",
      "47 0.34375 0.59375\n",
      "48 0.359375 0.578125\n",
      "49 0.359375 0.6875\n",
      "50 0.34375 0.65625\n",
      "51 0.375 0.515625\n",
      "52 0.390625 0.609375\n",
      "53 0.234375 0.625\n",
      "54 0.359375 0.625\n",
      "55 0.234375 0.59375\n",
      "56 0.40625 0.6875\n",
      "57 0.34375 0.765625\n",
      "58 0.296875 0.609375\n",
      "59 0.265625 0.59375\n",
      "60 0.25 0.65625\n",
      "61 0.390625 0.65625\n",
      "62 0.265625 0.65625\n",
      "63 0.46875 0.703125\n",
      "64 0.40625 0.59375\n",
      "65 0.359375 0.625\n",
      "66 0.28125 0.625\n",
      "67 0.3125 0.625\n",
      "68 0.328125 0.640625\n",
      "69 0.390625 0.625\n",
      "70 0.28125 0.640625\n",
      "71 0.328125 0.609375\n",
      "72 0.296875 0.59375\n",
      "73 0.125 0.703125\n",
      "74 0.359375 0.765625\n",
      "75 0.359375 0.65625\n",
      "76 0.34375 0.5625\n",
      "77 0.234375 0.671875\n",
      "78 0.34375 0.6875\n",
      "79 0.21875 0.734375\n",
      "80 0.3125 0.78125\n",
      "81 0.28125 0.6875\n",
      "82 0.34375 0.640625\n",
      "83 0.375 0.765625\n",
      "84 0.34375 0.640625\n",
      "85 0.328125 0.703125\n",
      "86 0.21875 0.75\n",
      "87 0.25 0.65625\n",
      "88 0.28125 0.640625\n",
      "89 0.3125 0.78125\n",
      "90 0.234375 0.71875\n",
      "91 0.328125 0.71875\n",
      "92 0.25 0.671875\n",
      "93 0.25 0.703125\n",
      "94 0.265625 0.546875\n",
      "95 0.296875 0.546875\n",
      "96 0.328125 0.625\n",
      "97 0.265625 0.75\n",
      "98 0.296875 0.671875\n",
      "99 0.265625 0.703125\n",
      "100 0.15625 0.734375\n",
      "101 0.234375 0.796875\n",
      "102 0.25 0.71875\n",
      "103 0.21875 0.828125\n",
      "104 0.21875 0.828125\n",
      "105 0.328125 0.765625\n",
      "106 0.21875 0.671875\n",
      "107 0.28125 0.84375\n",
      "108 0.21875 0.796875\n",
      "109 0.21875 0.78125\n",
      "110 0.25 0.65625\n",
      "111 0.25 0.8125\n",
      "112 0.21875 0.859375\n",
      "113 0.28125 0.796875\n",
      "114 0.234375 0.625\n",
      "115 0.21875 0.671875\n",
      "116 0.234375 0.859375\n",
      "117 0.265625 0.71875\n",
      "118 0.21875 0.765625\n",
      "119 0.234375 0.765625\n",
      "120 0.234375 0.6875\n",
      "121 0.234375 0.8125\n",
      "122 0.296875 0.828125\n",
      "123 0.25 0.796875\n",
      "124 0.234375 0.890625\n",
      "125 0.359375 0.765625\n",
      "126 0.203125 0.75\n",
      "127 0.328125 0.703125\n",
      "128 0.203125 0.78125\n",
      "129 0.265625 0.796875\n",
      "130 0.3125 0.828125\n",
      "131 0.21875 0.828125\n",
      "132 0.25 0.828125\n",
      "133 0.296875 0.84375\n",
      "134 0.203125 0.875\n",
      "135 0.34375 0.734375\n",
      "136 0.421875 0.765625\n",
      "137 0.15625 0.796875\n",
      "138 0.359375 0.75\n",
      "139 0.234375 0.75\n",
      "140 0.421875 0.71875\n",
      "141 0.28125 0.703125\n",
      "142 0.1875 0.6875\n",
      "143 0.21875 0.828125\n",
      "144 0.25 0.890625\n",
      "145 0.265625 0.9375\n",
      "146 0.171875 0.8125\n",
      "147 0.265625 0.84375\n",
      "148 0.296875 0.90625\n",
      "149 0.171875 0.875\n",
      "150 0.21875 0.765625\n",
      "151 0.25 0.875\n",
      "152 0.25 0.90625\n",
      "153 0.25 0.90625\n",
      "154 0.328125 0.796875\n",
      "155 0.296875 0.921875\n",
      "156 0.234375 0.84375\n",
      "157 0.25 0.875\n",
      "158 0.1875 0.9375\n",
      "159 0.234375 0.859375\n",
      "160 0.234375 0.890625\n",
      "161 0.28125 0.984375\n",
      "162 0.21875 0.90625\n",
      "163 0.21875 0.90625\n",
      "164 0.265625 0.953125\n",
      "165 0.28125 0.953125\n",
      "166 0.328125 0.984375\n",
      "167 0.28125 0.96875\n",
      "168 0.25 0.953125\n",
      "169 0.359375 0.921875\n",
      "170 0.34375 1.0\n",
      "171 0.328125 0.953125\n",
      "172 0.296875 0.96875\n",
      "173 0.359375 0.921875\n",
      "174 0.28125 0.9375\n",
      "175 0.375 0.984375\n",
      "176 0.359375 0.96875\n",
      "177 0.265625 0.984375\n",
      "178 0.21875 0.96875\n",
      "179 0.28125 0.9375\n",
      "180 0.359375 1.0\n",
      "181 0.34375 0.984375\n",
      "182 0.40625 0.984375\n",
      "183 0.296875 0.953125\n",
      "184 0.34375 0.984375\n",
      "185 0.3125 0.984375\n",
      "186 0.359375 0.96875\n",
      "187 0.375 0.984375\n",
      "188 0.53125 0.953125\n",
      "189 0.40625 0.921875\n",
      "190 0.453125 0.953125\n",
      "191 0.375 0.96875\n",
      "192 0.609375 0.9375\n",
      "193 0.40625 0.96875\n",
      "194 0.4375 0.96875\n",
      "195 0.390625 0.96875\n",
      "196 0.40625 0.984375\n",
      "197 0.4375 1.0\n",
      "198 0.546875 0.953125\n",
      "199 0.328125 1.0\n",
      "200 0.328125 0.984375\n",
      "201 0.328125 0.984375\n",
      "202 0.453125 0.96875\n",
      "203 0.34375 0.96875\n",
      "204 0.34375 0.984375\n",
      "205 0.359375 0.96875\n",
      "206 0.359375 0.984375\n",
      "207 0.421875 0.96875\n",
      "208 0.5 0.984375\n",
      "209 0.40625 1.0\n",
      "210 0.390625 0.96875\n",
      "211 0.546875 0.96875\n",
      "212 0.390625 0.984375\n",
      "213 0.5 0.921875\n",
      "214 0.578125 0.96875\n",
      "215 0.671875 0.9375\n",
      "216 0.484375 0.984375\n",
      "217 0.4375 0.90625\n",
      "218 0.453125 0.96875\n",
      "219 0.421875 0.953125\n",
      "220 0.625 0.9375\n",
      "221 0.5 0.953125\n",
      "222 0.578125 0.984375\n",
      "223 0.53125 0.9375\n",
      "224 0.5625 0.984375\n",
      "225 0.546875 0.984375\n",
      "226 0.5625 0.96875\n",
      "227 0.578125 0.984375\n",
      "228 0.5625 0.953125\n",
      "229 0.546875 0.90625\n",
      "230 0.546875 0.921875\n",
      "231 0.75 1.0\n",
      "232 0.546875 1.0\n",
      "233 0.671875 1.0\n",
      "234 0.5625 0.96875\n",
      "235 0.640625 0.984375\n",
      "236 0.6875 0.921875\n",
      "237 0.59375 0.90625\n",
      "238 0.71875 0.921875\n",
      "239 0.609375 1.0\n",
      "240 0.59375 0.953125\n",
      "241 0.65625 0.953125\n",
      "242 0.640625 0.984375\n",
      "243 0.6875 0.984375\n",
      "244 0.546875 0.9375\n",
      "245 0.71875 1.0\n",
      "246 0.71875 0.953125\n",
      "247 0.609375 1.0\n",
      "248 0.671875 0.96875\n",
      "249 0.625 0.953125\n",
      "250 0.53125 0.921875\n",
      "251 0.6875 0.984375\n",
      "252 0.625 0.921875\n",
      "253 0.65625 0.984375\n",
      "254 0.625 0.9375\n",
      "255 0.75 0.96875\n",
      "256 0.609375 0.984375\n",
      "257 0.640625 0.921875\n",
      "258 0.6875 0.984375\n",
      "259 0.671875 1.0\n",
      "260 0.625 0.9375\n",
      "261 0.65625 0.984375\n",
      "262 0.703125 0.96875\n",
      "263 0.734375 1.0\n",
      "264 0.65625 0.984375\n",
      "265 0.578125 0.9375\n",
      "266 0.59375 0.96875\n",
      "267 0.703125 0.921875\n",
      "268 0.734375 1.0\n",
      "269 0.734375 1.0\n",
      "270 0.703125 0.984375\n",
      "271 0.734375 0.984375\n",
      "272 0.6875 0.953125\n",
      "273 0.703125 0.96875\n",
      "274 0.71875 1.0\n",
      "275 0.65625 0.953125\n",
      "276 0.75 0.921875\n",
      "277 0.609375 0.984375\n",
      "278 0.6875 1.0\n",
      "279 0.6875 0.953125\n",
      "280 0.765625 1.0\n",
      "281 0.796875 1.0\n",
      "282 0.734375 0.96875\n",
      "283 0.671875 0.984375\n",
      "284 0.578125 1.0\n",
      "285 0.671875 0.953125\n",
      "286 0.671875 0.984375\n",
      "287 0.75 0.9375\n",
      "288 0.734375 0.984375\n",
      "289 0.71875 0.96875\n",
      "290 0.75 0.96875\n",
      "291 0.6875 0.984375\n",
      "292 0.65625 0.9375\n",
      "293 0.734375 0.984375\n",
      "294 0.65625 0.953125\n",
      "295 0.703125 0.96875\n",
      "296 0.6875 0.984375\n",
      "297 0.71875 0.984375\n",
      "298 0.734375 0.953125\n",
      "299 0.71875 0.9375\n",
      "300 0.734375 0.984375\n",
      "301 0.78125 0.953125\n",
      "302 0.75 0.9375\n",
      "303 0.75 0.953125\n",
      "304 0.796875 0.96875\n",
      "305 0.734375 1.0\n",
      "306 0.71875 0.921875\n",
      "307 0.796875 0.953125\n",
      "308 0.84375 0.96875\n",
      "309 0.75 0.96875\n",
      "310 0.71875 1.0\n",
      "311 0.828125 0.96875\n",
      "312 0.8125 0.984375\n",
      "313 0.78125 0.9375\n",
      "314 0.84375 0.96875\n",
      "315 0.6875 0.984375\n",
      "316 0.84375 0.953125\n",
      "317 0.8125 0.984375\n",
      "318 0.765625 0.9375\n",
      "319 0.71875 0.9375\n",
      "320 0.703125 0.9375\n",
      "321 0.671875 0.96875\n",
      "322 0.703125 0.921875\n",
      "323 0.765625 0.96875\n",
      "324 0.703125 0.953125\n",
      "325 0.828125 0.96875\n",
      "326 0.828125 0.96875\n",
      "327 0.78125 0.984375\n",
      "328 0.8125 0.953125\n",
      "329 0.796875 0.984375\n",
      "330 0.765625 0.9375\n",
      "331 0.890625 0.90625\n",
      "332 0.8125 0.90625\n",
      "333 0.8125 1.0\n",
      "334 0.78125 0.96875\n",
      "335 0.875 0.96875\n",
      "336 0.84375 0.984375\n",
      "337 0.796875 1.0\n",
      "338 0.8125 0.984375\n",
      "339 0.78125 0.9375\n",
      "340 0.875 0.953125\n",
      "341 0.8125 0.921875\n",
      "342 0.796875 0.90625\n",
      "343 0.796875 0.953125\n",
      "344 0.8125 0.984375\n",
      "345 0.890625 0.9375\n",
      "346 0.828125 0.9375\n",
      "347 0.78125 0.96875\n",
      "348 0.90625 0.953125\n",
      "349 0.828125 0.96875\n",
      "350 0.796875 0.953125\n",
      "351 0.734375 0.921875\n",
      "352 0.796875 0.984375\n",
      "353 0.765625 0.921875\n",
      "354 0.8125 0.90625\n",
      "355 0.765625 0.96875\n",
      "356 0.84375 0.96875\n",
      "357 0.875 0.953125\n",
      "358 0.8125 0.90625\n",
      "359 0.828125 0.96875\n",
      "360 0.828125 0.953125\n",
      "361 0.84375 0.984375\n",
      "362 0.859375 0.9375\n",
      "363 0.859375 0.953125\n",
      "364 0.859375 0.9375\n",
      "365 0.875 0.96875\n",
      "366 0.875 0.953125\n",
      "367 0.8125 0.953125\n",
      "368 0.90625 0.9375\n",
      "369 0.875 0.984375\n",
      "370 0.9375 0.890625\n",
      "371 0.875 0.9375\n",
      "372 0.796875 0.921875\n",
      "373 0.828125 0.921875\n",
      "374 0.90625 0.921875\n",
      "375 0.8125 0.9375\n",
      "376 0.8125 0.90625\n",
      "377 0.90625 0.921875\n",
      "378 0.765625 1.0\n",
      "379 0.78125 0.953125\n",
      "380 0.78125 0.953125\n",
      "381 0.875 0.953125\n",
      "382 0.875 0.9375\n",
      "383 0.84375 0.890625\n",
      "384 0.796875 0.9375\n",
      "385 0.859375 0.96875\n",
      "386 0.8125 0.96875\n",
      "387 0.90625 0.953125\n",
      "388 0.921875 0.9375\n",
      "389 0.890625 0.953125\n",
      "390 0.96875 0.921875\n",
      "391 0.84375 0.875\n",
      "392 0.875 0.921875\n",
      "393 0.828125 0.9375\n",
      "394 0.921875 0.9375\n",
      "395 0.890625 0.9375\n",
      "396 0.921875 0.921875\n",
      "397 0.890625 1.0\n",
      "398 0.875 0.984375\n",
      "399 0.921875 0.9375\n",
      "400 0.828125 0.953125\n",
      "401 0.828125 0.90625\n",
      "402 0.9375 0.953125\n",
      "403 0.8125 0.890625\n",
      "404 0.953125 0.953125\n",
      "405 0.9375 0.890625\n",
      "406 0.90625 0.96875\n",
      "407 0.890625 0.984375\n",
      "408 0.875 0.9375\n",
      "409 0.921875 0.984375\n",
      "410 0.859375 0.96875\n",
      "411 0.890625 0.953125\n",
      "412 0.921875 0.96875\n",
      "413 0.921875 1.0\n",
      "414 0.921875 0.96875\n",
      "415 0.875 0.90625\n",
      "416 0.96875 0.96875\n",
      "417 0.890625 0.921875\n",
      "418 0.90625 0.953125\n",
      "419 0.875 0.9375\n",
      "420 0.875 0.921875\n",
      "421 0.96875 0.953125\n",
      "422 0.921875 0.96875\n",
      "423 0.890625 0.875\n",
      "424 0.84375 0.90625\n",
      "425 0.921875 0.984375\n",
      "426 0.953125 0.890625\n",
      "427 1.0 0.90625\n",
      "428 0.890625 0.9375\n",
      "429 0.921875 0.9375\n",
      "430 0.9375 0.953125\n",
      "431 0.96875 0.953125\n",
      "432 0.90625 0.9375\n",
      "433 0.953125 0.875\n",
      "434 0.953125 0.890625\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "435 0.96875 0.90625\n",
      "436 0.9375 0.953125\n",
      "437 0.96875 0.953125\n",
      "438 0.953125 0.890625\n",
      "439 0.921875 0.953125\n",
      "440 0.953125 0.90625\n",
      "441 0.90625 0.984375\n",
      "442 0.96875 0.96875\n",
      "443 0.984375 0.9375\n",
      "444 0.921875 0.9375\n",
      "445 0.96875 0.90625\n",
      "446 0.921875 0.96875\n",
      "447 0.890625 0.875\n",
      "448 0.953125 0.953125\n",
      "449 0.984375 0.953125\n",
      "450 0.921875 0.953125\n",
      "451 1.0 0.90625\n",
      "452 0.984375 0.96875\n",
      "453 1.0 0.90625\n",
      "454 0.953125 0.953125\n",
      "455 0.96875 0.9375\n",
      "456 0.953125 0.90625\n",
      "457 1.0 0.921875\n",
      "458 0.984375 0.96875\n",
      "459 0.984375 0.90625\n",
      "460 0.984375 0.984375\n",
      "461 1.0 0.921875\n",
      "462 0.984375 0.953125\n",
      "463 0.96875 0.921875\n",
      "464 1.0 0.921875\n",
      "465 0.984375 0.859375\n",
      "466 1.0 0.90625\n",
      "467 1.0 0.890625\n",
      "468 1.0 0.90625\n",
      "469 1.0 0.875\n",
      "470 1.0 0.84375\n",
      "471 1.0 0.875\n",
      "472 0.984375 0.859375\n",
      "473 1.0 0.859375\n",
      "474 1.0 0.921875\n",
      "475 0.984375 0.96875\n",
      "476 1.0 0.875\n",
      "477 1.0 0.890625\n",
      "478 1.0 0.921875\n",
      "479 1.0 0.890625\n",
      "480 1.0 0.953125\n",
      "481 1.0 0.90625\n",
      "482 1.0 0.890625\n",
      "483 1.0 0.90625\n",
      "484 1.0 0.90625\n",
      "485 1.0 0.890625\n",
      "486 1.0 0.921875\n",
      "487 1.0 0.96875\n",
      "488 1.0 0.9375\n",
      "489 1.0 0.921875\n",
      "490 1.0 0.890625\n",
      "491 1.0 0.890625\n",
      "492 1.0 0.9375\n",
      "493 1.0 0.90625\n",
      "494 0.984375 0.9375\n",
      "495 1.0 0.875\n",
      "496 1.0 0.890625\n",
      "497 1.0 0.9375\n",
      "498 1.0 0.921875\n",
      "499 0.984375 0.921875\n",
      "500 1.0 0.921875\n",
      "501 1.0 0.875\n",
      "502 1.0 0.90625\n",
      "503 1.0 0.953125\n",
      "504 1.0 0.921875\n",
      "505 1.0 0.96875\n",
      "506 1.0 0.953125\n",
      "507 1.0 0.921875\n",
      "508 1.0 0.921875\n",
      "509 1.0 0.890625\n",
      "510 1.0 0.96875\n",
      "511 1.0 0.921875\n",
      "512 1.0 0.921875\n",
      "513 1.0 0.859375\n",
      "514 1.0 0.875\n",
      "515 1.0 0.921875\n",
      "516 1.0 0.9375\n",
      "517 1.0 0.890625\n",
      "518 1.0 0.90625\n",
      "519 1.0 0.875\n",
      "520 1.0 0.90625\n",
      "521 1.0 0.9375\n",
      "522 1.0 0.921875\n",
      "523 1.0 0.875\n",
      "524 1.0 0.875\n",
      "525 1.0 0.921875\n",
      "526 1.0 0.953125\n",
      "527 1.0 0.90625\n",
      "528 1.0 0.90625\n",
      "529 1.0 0.90625\n",
      "530 1.0 0.890625\n",
      "531 1.0 0.90625\n",
      "532 1.0 0.921875\n",
      "533 1.0 0.921875\n",
      "534 1.0 0.953125\n",
      "535 1.0 0.875\n",
      "536 1.0 0.90625\n",
      "537 1.0 0.859375\n",
      "538 1.0 0.890625\n",
      "539 1.0 0.9375\n",
      "540 1.0 0.9375\n",
      "541 1.0 0.953125\n",
      "542 1.0 0.890625\n",
      "543 1.0 0.90625\n",
      "544 1.0 0.84375\n",
      "545 1.0 0.890625\n",
      "546 1.0 0.890625\n",
      "547 1.0 0.953125\n",
      "548 1.0 0.9375\n",
      "549 1.0 0.9375\n",
      "550 1.0 0.890625\n",
      "551 1.0 0.96875\n",
      "552 1.0 0.921875\n",
      "553 1.0 0.890625\n",
      "554 1.0 0.90625\n",
      "555 1.0 0.96875\n",
      "556 1.0 0.921875\n",
      "557 1.0 0.953125\n",
      "558 1.0 0.890625\n",
      "559 1.0 0.9375\n",
      "560 1.0 0.9375\n",
      "561 1.0 0.90625\n",
      "562 1.0 0.9375\n",
      "563 1.0 0.953125\n",
      "564 1.0 0.875\n",
      "565 1.0 0.90625\n",
      "566 1.0 0.859375\n",
      "567 1.0 0.875\n",
      "568 1.0 0.921875\n",
      "569 1.0 0.84375\n",
      "570 1.0 0.890625\n",
      "571 1.0 0.890625\n",
      "572 1.0 0.953125\n",
      "573 1.0 0.90625\n",
      "574 1.0 0.921875\n",
      "575 1.0 0.921875\n",
      "576 1.0 0.921875\n",
      "577 1.0 0.859375\n",
      "578 1.0 0.9375\n",
      "579 1.0 0.953125\n",
      "580 1.0 0.921875\n",
      "581 1.0 0.875\n",
      "582 1.0 0.875\n",
      "583 1.0 0.875\n",
      "584 1.0 0.921875\n",
      "585 1.0 0.890625\n",
      "586 1.0 0.890625\n",
      "587 1.0 0.890625\n",
      "588 1.0 0.90625\n",
      "589 1.0 0.875\n",
      "590 1.0 0.90625\n",
      "591 1.0 0.859375\n",
      "592 1.0 0.90625\n",
      "593 1.0 0.84375\n",
      "594 1.0 0.859375\n",
      "595 1.0 0.890625\n",
      "596 1.0 0.90625\n",
      "597 1.0 0.875\n",
      "598 1.0 0.953125\n",
      "599 1.0 0.875\n",
      "600 1.0 0.859375\n",
      "601 1.0 0.9375\n",
      "602 1.0 0.875\n",
      "603 1.0 0.859375\n",
      "604 1.0 0.90625\n",
      "605 1.0 0.90625\n",
      "606 1.0 0.78125\n",
      "607 1.0 0.828125\n",
      "608 1.0 0.9375\n",
      "609 1.0 0.921875\n",
      "610 1.0 0.90625\n",
      "611 1.0 0.953125\n",
      "612 1.0 0.890625\n",
      "613 1.0 0.9375\n",
      "614 1.0 0.921875\n",
      "615 1.0 0.796875\n",
      "616 1.0 0.890625\n",
      "617 1.0 0.921875\n",
      "618 1.0 0.90625\n",
      "619 1.0 0.890625\n",
      "620 1.0 0.859375\n",
      "621 1.0 0.921875\n",
      "622 1.0 0.828125\n",
      "623 1.0 0.875\n",
      "624 1.0 0.953125\n",
      "625 1.0 0.84375\n",
      "626 1.0 0.9375\n",
      "627 1.0 0.9375\n",
      "628 1.0 0.859375\n",
      "629 1.0 0.9375\n",
      "630 1.0 0.90625\n",
      "631 1.0 0.9375\n",
      "632 1.0 0.921875\n",
      "633 1.0 0.90625\n",
      "634 1.0 0.90625\n",
      "635 1.0 0.890625\n",
      "636 1.0 0.78125\n",
      "637 1.0 0.90625\n",
      "638 1.0 0.890625\n",
      "639 1.0 0.921875\n",
      "640 1.0 0.75\n",
      "641 1.0 0.875\n",
      "642 1.0 0.875\n",
      "643 1.0 0.90625\n",
      "644 1.0 0.953125\n",
      "645 1.0 0.921875\n",
      "646 1.0 0.890625\n",
      "647 1.0 0.859375\n",
      "648 1.0 0.84375\n",
      "649 1.0 0.90625\n",
      "650 1.0 0.84375\n",
      "651 1.0 0.84375\n",
      "652 1.0 0.921875\n",
      "653 1.0 0.90625\n",
      "654 1.0 0.921875\n",
      "655 1.0 0.921875\n",
      "656 1.0 0.921875\n",
      "657 1.0 0.84375\n",
      "658 1.0 0.84375\n",
      "659 1.0 0.90625\n",
      "660 1.0 0.953125\n",
      "661 1.0 0.890625\n",
      "662 1.0 0.875\n",
      "663 1.0 0.84375\n",
      "664 1.0 0.84375\n",
      "665 1.0 0.8125\n",
      "666 1.0 0.859375\n",
      "667 1.0 0.90625\n",
      "668 1.0 0.90625\n",
      "669 1.0 0.875\n",
      "670 1.0 0.921875\n",
      "671 1.0 0.84375\n",
      "672 1.0 0.953125\n",
      "673 1.0 0.84375\n",
      "674 1.0 0.8125\n",
      "675 1.0 0.84375\n",
      "676 1.0 0.921875\n",
      "677 1.0 0.953125\n",
      "678 1.0 0.84375\n",
      "679 1.0 0.859375\n",
      "680 1.0 0.859375\n",
      "681 1.0 0.90625\n",
      "682 1.0 0.90625\n",
      "683 1.0 0.90625\n",
      "684 1.0 0.828125\n",
      "685 1.0 0.875\n",
      "686 1.0 0.9375\n",
      "687 1.0 0.859375\n",
      "688 1.0 0.859375\n",
      "689 1.0 0.84375\n",
      "690 1.0 0.953125\n",
      "691 1.0 0.84375\n",
      "692 1.0 0.859375\n",
      "693 1.0 0.9375\n",
      "694 1.0 0.890625\n",
      "695 1.0 0.859375\n",
      "696 1.0 0.875\n",
      "697 1.0 0.875\n",
      "698 1.0 0.9375\n",
      "699 1.0 0.890625\n",
      "700 1.0 0.921875\n",
      "701 1.0 0.828125\n",
      "702 1.0 0.84375\n",
      "703 1.0 0.90625\n",
      "704 1.0 0.859375\n",
      "705 1.0 0.90625\n",
      "706 1.0 0.921875\n",
      "707 1.0 0.9375\n",
      "708 1.0 0.84375\n",
      "709 1.0 0.875\n",
      "710 1.0 0.90625\n",
      "711 1.0 0.90625\n",
      "712 1.0 0.890625\n",
      "713 1.0 0.921875\n",
      "714 1.0 0.90625\n",
      "715 1.0 0.890625\n",
      "716 1.0 0.8125\n",
      "717 1.0 0.875\n",
      "718 1.0 0.890625\n",
      "719 1.0 0.890625\n",
      "720 1.0 0.90625\n",
      "721 1.0 0.875\n",
      "722 1.0 0.84375\n",
      "723 1.0 0.9375\n",
      "724 1.0 0.90625\n",
      "725 1.0 0.84375\n",
      "726 1.0 0.9375\n",
      "727 1.0 0.875\n",
      "728 1.0 0.8125\n",
      "729 1.0 0.84375\n",
      "730 1.0 0.9375\n",
      "731 1.0 0.84375\n",
      "732 1.0 0.875\n",
      "733 1.0 0.921875\n",
      "734 1.0 0.78125\n",
      "735 1.0 0.78125\n",
      "736 1.0 0.859375\n",
      "737 1.0 0.84375\n",
      "738 1.0 0.90625\n",
      "739 1.0 0.859375\n",
      "740 1.0 0.875\n",
      "741 1.0 0.859375\n",
      "742 1.0 0.890625\n",
      "743 1.0 0.875\n",
      "744 1.0 0.890625\n",
      "745 1.0 0.859375\n",
      "746 1.0 0.8125\n",
      "747 1.0 0.859375\n",
      "748 1.0 0.953125\n",
      "749 1.0 0.84375\n",
      "750 1.0 0.890625\n",
      "751 1.0 0.796875\n",
      "752 1.0 0.890625\n",
      "753 1.0 0.796875\n",
      "754 1.0 0.84375\n",
      "755 1.0 0.890625\n",
      "756 1.0 0.875\n",
      "757 1.0 0.890625\n",
      "758 1.0 0.921875\n",
      "759 1.0 0.84375\n",
      "760 1.0 0.875\n",
      "761 1.0 0.859375\n",
      "762 1.0 0.953125\n",
      "763 1.0 0.890625\n",
      "764 1.0 0.859375\n",
      "765 1.0 0.84375\n",
      "766 1.0 0.828125\n",
      "767 1.0 0.8125\n",
      "768 1.0 0.84375\n",
      "769 1.0 0.859375\n",
      "770 1.0 0.875\n",
      "771 1.0 0.890625\n",
      "772 1.0 0.90625\n",
      "773 1.0 0.90625\n",
      "774 1.0 0.953125\n",
      "775 1.0 0.90625\n",
      "776 1.0 0.890625\n",
      "777 1.0 0.890625\n",
      "778 1.0 0.921875\n",
      "779 1.0 0.90625\n",
      "780 1.0 0.90625\n",
      "781 1.0 0.90625\n",
      "782 1.0 0.796875\n",
      "783 1.0 0.765625\n",
      "784 1.0 0.921875\n",
      "785 1.0 0.875\n",
      "786 1.0 0.890625\n",
      "787 1.0 0.90625\n",
      "788 1.0 0.90625\n",
      "789 1.0 0.890625\n",
      "790 1.0 0.859375\n",
      "791 1.0 0.890625\n",
      "792 1.0 0.875\n",
      "793 1.0 0.796875\n",
      "794 1.0 0.859375\n",
      "795 1.0 0.828125\n",
      "796 1.0 0.890625\n",
      "797 1.0 0.875\n",
      "798 1.0 0.890625\n",
      "799 1.0 0.8125\n",
      "800 1.0 0.875\n",
      "801 1.0 0.921875\n",
      "802 1.0 0.90625\n",
      "803 1.0 0.890625\n",
      "804 1.0 0.90625\n",
      "805 1.0 0.890625\n",
      "806 1.0 0.90625\n",
      "807 1.0 0.9375\n",
      "808 1.0 0.90625\n",
      "809 1.0 0.90625\n",
      "810 1.0 0.859375\n",
      "811 1.0 0.859375\n",
      "812 1.0 0.890625\n",
      "813 1.0 0.875\n",
      "814 1.0 0.8125\n",
      "815 1.0 0.875\n",
      "816 1.0 0.921875\n",
      "817 1.0 0.9375\n",
      "818 1.0 0.890625\n",
      "819 1.0 0.90625\n",
      "820 1.0 0.921875\n",
      "821 1.0 0.875\n",
      "822 1.0 0.9375\n",
      "823 1.0 0.90625\n",
      "824 1.0 0.875\n",
      "825 1.0 0.84375\n",
      "826 1.0 0.875\n",
      "827 1.0 0.8125\n",
      "828 1.0 0.8125\n",
      "829 1.0 0.890625\n",
      "830 1.0 0.78125\n",
      "831 1.0 0.890625\n",
      "832 1.0 0.890625\n",
      "833 1.0 0.84375\n",
      "834 1.0 0.859375\n",
      "835 1.0 0.875\n",
      "836 1.0 0.890625\n",
      "837 1.0 0.9375\n",
      "838 1.0 0.953125\n",
      "839 1.0 0.875\n",
      "840 1.0 0.890625\n",
      "841 1.0 0.78125\n",
      "842 1.0 0.921875\n",
      "843 1.0 0.875\n",
      "844 1.0 0.84375\n",
      "845 1.0 0.859375\n",
      "846 1.0 0.828125\n",
      "847 1.0 0.8125\n",
      "848 1.0 0.921875\n",
      "849 1.0 0.890625\n",
      "850 1.0 0.84375\n",
      "851 1.0 0.96875\n",
      "852 1.0 0.90625\n",
      "853 1.0 0.9375\n",
      "854 1.0 0.875\n",
      "855 1.0 0.890625\n",
      "856 1.0 0.859375\n",
      "857 1.0 0.890625\n",
      "858 1.0 0.8125\n",
      "859 1.0 0.875\n",
      "860 1.0 0.875\n",
      "861 1.0 0.875\n",
      "862 1.0 0.859375\n",
      "863 1.0 0.875\n",
      "864 1.0 0.9375\n",
      "865 1.0 0.796875\n",
      "866 1.0 0.84375\n",
      "867 1.0 0.90625\n",
      "868 1.0 0.875\n",
      "869 1.0 0.890625\n",
      "870 1.0 0.953125\n",
      "871 1.0 0.890625\n",
      "872 1.0 0.90625\n",
      "873 1.0 0.828125\n",
      "874 1.0 0.96875\n",
      "875 1.0 0.90625\n",
      "876 1.0 0.84375\n",
      "877 1.0 0.765625\n",
      "878 1.0 0.96875\n",
      "879 1.0 0.890625\n",
      "880 1.0 0.890625\n",
      "881 1.0 0.84375\n",
      "882 1.0 0.890625\n",
      "883 1.0 0.84375\n",
      "884 1.0 0.859375\n",
      "885 1.0 0.84375\n",
      "886 1.0 0.859375\n",
      "887 1.0 0.875\n",
      "888 1.0 0.921875\n",
      "889 1.0 0.90625\n",
      "890 1.0 0.90625\n",
      "891 1.0 0.859375\n",
      "892 1.0 0.859375\n",
      "893 1.0 0.9375\n",
      "894 1.0 0.84375\n",
      "895 1.0 0.859375\n",
      "896 1.0 0.90625\n",
      "897 1.0 0.9375\n",
      "898 1.0 0.84375\n",
      "899 1.0 0.890625\n",
      "900 1.0 0.828125\n",
      "901 1.0 0.90625\n",
      "902 1.0 0.90625\n",
      "903 1.0 0.859375\n",
      "904 1.0 0.875\n",
      "905 1.0 0.84375\n",
      "906 1.0 0.875\n",
      "907 1.0 0.875\n",
      "908 1.0 0.859375\n",
      "909 1.0 0.875\n",
      "910 1.0 0.9375\n",
      "911 1.0 0.796875\n",
      "912 1.0 0.90625\n",
      "913 1.0 0.859375\n",
      "914 1.0 0.9375\n",
      "915 1.0 0.875\n",
      "916 1.0 0.859375\n",
      "917 1.0 0.890625\n",
      "918 1.0 0.890625\n",
      "919 1.0 0.875\n",
      "920 1.0 0.953125\n",
      "921 1.0 0.921875\n",
      "922 1.0 0.921875\n",
      "923 1.0 0.890625\n",
      "924 1.0 0.9375\n",
      "925 1.0 0.859375\n",
      "926 1.0 0.90625\n",
      "927 1.0 0.921875\n",
      "928 1.0 0.859375\n",
      "929 1.0 0.859375\n",
      "930 1.0 0.875\n",
      "931 1.0 0.890625\n",
      "932 1.0 0.890625\n",
      "933 1.0 0.859375\n",
      "934 1.0 0.859375\n",
      "935 1.0 0.828125\n",
      "936 1.0 0.96875\n",
      "937 1.0 0.875\n",
      "938 1.0 0.75\n",
      "939 1.0 0.9375\n",
      "940 1.0 0.828125\n",
      "941 1.0 0.890625\n",
      "942 1.0 0.828125\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "943 1.0 0.859375\n",
      "944 1.0 0.875\n",
      "945 1.0 0.921875\n",
      "946 1.0 0.890625\n",
      "947 1.0 0.921875\n",
      "948 1.0 0.9375\n",
      "949 1.0 0.953125\n",
      "950 1.0 0.875\n",
      "951 1.0 0.859375\n",
      "952 1.0 0.890625\n",
      "953 1.0 0.84375\n",
      "954 1.0 0.875\n",
      "955 1.0 0.875\n",
      "956 1.0 0.90625\n",
      "957 1.0 0.84375\n",
      "958 1.0 0.828125\n",
      "959 1.0 0.75\n",
      "960 1.0 0.890625\n",
      "961 1.0 0.875\n",
      "962 1.0 0.921875\n",
      "963 1.0 0.796875\n",
      "964 1.0 0.875\n",
      "965 1.0 0.90625\n",
      "966 1.0 0.921875\n",
      "967 1.0 0.796875\n",
      "968 1.0 0.875\n",
      "969 1.0 0.921875\n",
      "970 1.0 0.828125\n",
      "971 1.0 0.9375\n",
      "972 1.0 0.890625\n",
      "973 1.0 0.921875\n",
      "974 1.0 0.875\n",
      "975 1.0 0.9375\n",
      "976 1.0 0.90625\n",
      "977 1.0 0.953125\n",
      "978 1.0 0.859375\n",
      "979 1.0 0.828125\n",
      "980 1.0 0.9375\n",
      "981 1.0 0.953125\n",
      "982 1.0 0.90625\n",
      "983 1.0 0.828125\n",
      "984 1.0 0.78125\n",
      "985 1.0 0.90625\n",
      "986 1.0 0.921875\n",
      "987 1.0 0.90625\n",
      "988 1.0 0.921875\n",
      "989 1.0 0.890625\n",
      "990 1.0 0.90625\n",
      "991 1.0 0.890625\n",
      "992 1.0 0.78125\n",
      "993 1.0 0.859375\n",
      "994 1.0 0.765625\n",
      "995 1.0 0.8125\n",
      "996 1.0 0.890625\n",
      "997 1.0 0.890625\n",
      "998 1.0 0.875\n",
      "999 1.0 0.84375\n"
     ]
    }
   ],
   "source": [
    "# define the discriminator model\n",
    "model = define_discriminator()\n",
    "# fit the model\n",
    "train_discriminator(model)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "\"*The goal is to train a generator model, not a discriminator model, and that is where the complexity of GANs truly lies.*\" "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The Generator Model\n",
    "*We will define a small latent space of five dimensions and use the standard approach in the GAN literature of using a Gaussian distribution for each variable in the latent space. We will generate new inputs by drawing random numbers from a standard Gaussian distribution, i.e. mean of zero and a standard deviation of one.*\n",
    "\n",
    "* Specs:\n",
    "> * Single Hidden Layer with 5 nodes\n",
    "> * ReLU activation Function\n",
    "> * He weight initialization\n",
    "> * Output layer will have 2 nodes+ will use linear activation function"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define the generator model unit\n",
    "def define_generator(latent_dim, n_outputs=2):\n",
    "\tmodel = Sequential()\n",
    "\tmodel.add(Dense(15, activation='relu', kernel_initializer='he_uniform', input_dim=latent_dim))\n",
    "\tmodel.add(Dense(n_outputs, activation='linear'))\n",
    "\treturn model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Model: \"sequential_3\"\n",
      "_________________________________________________________________\n",
      "Layer (type)                 Output Shape              Param #   \n",
      "=================================================================\n",
      "dense_5 (Dense)              (None, 15)                90        \n",
      "_________________________________________________________________\n",
      "dense_6 (Dense)              (None, 2)                 32        \n",
      "=================================================================\n",
      "Total params: 122\n",
      "Trainable params: 122\n",
      "Non-trainable params: 0\n",
      "_________________________________________________________________\n"
     ]
    }
   ],
   "source": [
    "# define the discriminator model\n",
    "model = define_generator(5)\n",
    "# summarize the model\n",
    "model.summary()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [],
   "source": [
    "# generate points in latent space as input for the generator\n",
    "def generate_latent_points(latent_dim, n):\n",
    "\t# generate points in the latent space\n",
    "\tx_input = np.random.randn(latent_dim * n)\n",
    "\t# reshape into a batch of inputs for the network\n",
    "\tx_input = x_input.reshape(n, latent_dim)\n",
    "\treturn x_input"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "# use the generator to generate n fake examples and plot the results\n",
    "def generate_fake_samples(generator, latent_dim, n):\n",
    "\t# generate points in latent space\n",
    "\tx_input = generate_latent_points(latent_dim, n)\n",
    "\t# predict outputs\n",
    "\tX = generator.predict(x_input)\n",
    "    # create class labels\n",
    "\ty = np.zeros((n, 1))\n",
    "\treturn X, y"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "*When the discriminator is good at detecting fake samples, the generator is updated more, and when the discriminator model is relatively poor or confused when detecting fake samples, the generator model is updated less.*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# define the combined generator and discriminator model, for updating the generator\n",
    "def define_gan(generator, discriminator):\n",
    "\t# make weights in the discriminator not trainable\n",
    "\tdiscriminator.trainable = False\n",
    "\t# connect them\n",
    "\tmodel = Sequential()\n",
    "\t# add generator\n",
    "\tmodel.add(generator)\n",
    "\t# add the discriminator\n",
    "\tmodel.add(discriminator)\n",
    "\t# compile model\n",
    "\tmodel.compile(loss='binary_crossentropy', optimizer='adam')\n",
    "\treturn model"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [],
   "source": [
    "# train the generator and discriminator\n",
    "def train(g_model, d_model, gan_model, latent_dim, n_epochs=10000, n_batch=128, n_eval=2000):\n",
    "\t# determine half the size of one batch, for updating the discriminator\n",
    "\thalf_batch = int(n_batch / 2)\n",
    "\t# manually enumerate epochs\n",
    "\tfor i in range(n_epochs):\n",
    "\t\t# prepare real samples\n",
    "\t\tx_real, y_real = generate_real_samples(half_batch)\n",
    "\t\t# prepare fake examples\n",
    "\t\tx_fake, y_fake = generate_fake_samples(g_model, latent_dim, half_batch)\n",
    "\t\t# update discriminator\n",
    "\t\td_model.train_on_batch(x_real, y_real)\n",
    "\t\td_model.train_on_batch(x_fake, y_fake)\n",
    "\t\t# prepare points in latent space as input for the generator\n",
    "\t\tx_gan = generate_latent_points(latent_dim, n_batch)\n",
    "\t\t# create inverted labels for the fake samples\n",
    "\t\ty_gan = np.ones((n_batch, 1))\n",
    "\t\t# update the generator via the discriminator's error\n",
    "\t\tgan_model.train_on_batch(x_gan, y_gan)\n",
    "\t\t# evaluate the model every n_eval epochs\n",
    "\t\tif (i+1) % n_eval == 0:\n",
    "\t\t\tsummarize_performance(i, g_model, d_model, latent_dim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "metadata": {},
   "outputs": [],
   "source": [
    "# evaluate the discriminator and plot real and fake points\n",
    "def summarize_performance(epoch, generator, discriminator, latent_dim, n=100):\n",
    "\t# prepare real samples\n",
    "\tx_real, y_real = generate_real_samples(n)\n",
    "\t# evaluate discriminator on real examples\n",
    "\t_, acc_real = discriminator.evaluate(x_real, y_real, verbose=0)\n",
    "\t# prepare fake examples\n",
    "\tx_fake, y_fake = generate_fake_samples(generator, latent_dim, n)\n",
    "\t# evaluate discriminator on fake examples\n",
    "\t_, acc_fake = discriminator.evaluate(x_fake, y_fake, verbose=0)\n",
    "\t# summarize discriminator performance\n",
    "\tprint(epoch, acc_real, acc_fake)\n",
    "\t# scatter plot real and fake data points\n",
    "\tpyplot.scatter(x_real[:, 0], x_real[:, 1], color='red')\n",
    "\tpyplot.scatter(x_fake[:, 0], x_fake[:, 1], color='blue')\n",
    "\tpyplot.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1999 0.7400000095367432 0.4399999976158142\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# size of the latent space\n",
    "latent_dim = 5\n",
    "# create the discriminator\n",
    "discriminator = define_discriminator()\n",
    "# create the generator\n",
    "generator = define_generator(latent_dim)\n",
    "# create the gan\n",
    "gan_model = define_gan(generator, discriminator)\n",
    "# train model\n",
    "train(generator, discriminator, gan_model, latent_dim)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
